package com.yunhe.common.constant;

import com.yunhe.common.util.MD5Util;

/**
 * 缓存常量定义
 * @author liuronglei
 */
public class CacheConsts {

    public static final String SPLIT_STR = ":";
    public static final String SPLIT_IDS = ",";
    public static final String SPLIT_FIELD = "-";
    public static final String SPLIT_TYPE = ";";
    public static final int KEY_MAX_SIZE = 32;

    public static final String KEY_GENERATOR = "methodKeyGenerator";

    // 缓存命名空间定义
    public final class Region {
        public static final String USER = "User";
        public static final String FIRM = "Firm";
        public static final String STATION = "Station";
        public static final String AREA = "Area";
        public static final String MEASUREMENT = "Measurement";
        // 点号
        public static final String ANALOG = "Analog";
        // 点号数据类型
        public static final String POINT_DATA_TYPE = "PointDataType";
        // 设备
        public static final String DEVICE = "Device";
        // 设备类型
        public static final String DEVICE_TYPE = "DeviceType";
        // 能量单元
        public static final String ENERGY_UNIT = "EnergyUnit";
        // 告警规则
        public static final String ALARM_RULE = "AlarmRule";
        // 告警状态
        public static final String ABNORMAL_STATUS = "AbnormalStatus";
        // 待处理的告警事件
        public static final String ALARM_EVENT_PENDING = "AlarmEventPending";
        // 告警状态
        public static final String ALARM_STATUS = "AlarmStatus";
        // 异常规则实例
        public static final String ALARM_RULE_INSTANCE = "AlarmRuleInstance";
    }

    public static class NameSpace {
        public static String value(String... keys) {
            StringBuilder result = new StringBuilder();
            for (String key : keys) {
                result.append(key).append(SPLIT_STR);
            }
            return result.substring(0, result.length() - 1);
        }
    }

    // 对key进行编号
    public static String encode(String key) {
        if (key.length() > KEY_MAX_SIZE) {
            key = MD5Util.encode(key);
        }
        return key;
    }

    // 生存时间定义
    public enum LIVE_TIME {
        MINUTE(60, "1分钟"),
        MINUTE_5(60*5, "5分钟"),
        HOUR_HALF(60*30, "半小时"),
        HOUR(60*60, "1小时"),
        DAY(60*60*12, "1天"),
        WEEK(60*60*12*7, "1周"),
        MONTH_HALF(60*60*12*15, "半月"),
        MONTH(60*60*12*30, "1月"),
        MONTH_3(60*60*12*30*3, "3月");
        private int value;
        private String title;
        LIVE_TIME(int value, String title) {
            this.value = value;
            this.title = title;
        }
        public int value() {
            return value;
        }
        public String title() {
            return title;
        }
    }

    // Key前缀定义
    private enum KEY_PRE {
        AUTHORITY("authority", "权限"),
        DEVICE("device", "设备"),
        REALTIME("realtime", "实时量测"),
        ABNORMAL("abnormal", "异常"),
        OPTION("option", "参数"),
        TASK("task", "任务");
        private String value;
        private String title;
        KEY_PRE(String value, String title) {
            this.value = value;
            this.title = title;
        }
        public String value() {
            return value;
        }
        public String title() {
            return title;
        }
    }

    // Key定义
    public enum KEY {
        ANALOG_STATUS("analogStatus", "点号状态"),
        ALARM_STATUS("alarmStatus", "异常状态"),
        FIRM("firm", "单位"),
        STATION("station", "电站"),
        USER("user", "用户"),
        MEASURE_POINT_MAP("measurePointMap", "量测映射"),
        MEASURE_OBJ("measureObj", "量测对象"),
        MEASURE_BACKUP("measureObjBackup", "量测对象备份"),
        USER_PECULIAR("UserPeculiar", "用户异样标记"),
        USER_FAILED_LOGIN_COUNT("userFailedLogin", "用户登陆失败标识"),
        REGISTER_VERIFICATION_CODE("registerVerificationCode", "注册验证码"),
        STATION_BASE_INFO("stationBaseInfo","电站基本信息"),
        VIRTUAL_ANALOG("virtualAnalog","虚拟点号列表"),
        CUSTOM_REALTIME("custome_realtime", "自定义实时值"),
        SYSTEM_DATA_STORAGE("SystemDataStorage", "系统切数据点号缓存"),
        All_AREA("AllArea", "全部地区"),
        STATION_ID_TIMEZONE("stationId_timezone", "电站ID对应时区"),
        STATION_CODE_TIMEZONE("stationCode_timezone", "电站CODE对应时区"),
        STATION_ID_WEBUSER("stationId_webuser", "电站ID对应APP属性"),
        EnergyUnitStartRealSoc("EnergyUnitStartRealSoc", "能量单元实时SOC"),
        EnergyUnitStartRealSocTime("EnergyUnitStartRealSocTime", "能量单元实时SOC时间"),
        Station("Station", "电站"),
        Station_Device("Station_Device", "电站下的设备"),
        Station_EnergyUnit("Station_EnergyUnit", "电站下的能量单元"),
        EnergyUnit("EnergyUnit", "能量单元"),
        EnergyUnit_Device("EnergyUnit_Device", "能量单元下设备"),
        Device("Device", "设备"),
        Analog("Analog", "点号"),
        Device_Analog("Device_Analog", "设备点号"),
        HeartbeatTimeMillis("HeartbeatTimeMillis", "心跳时间记录"),
        ABNORMAL_STATUS("AbnormalStatus", "异常处理状态"),
        ABNORMAL_RULE_MEAS("abnormalRuleMeasPns", "告警量测点号"),
        ABNORMAL_RULE_READY_SET("ReadyEventMapKeySet", "待处理告警列表"),
        FORMULA_OBJECT("formulaObjects", "告警规则公式对象"),
        DEVICE_LABEL_KEY("DeviceLabelKey", "设备标签密钥"),
        ENERGY_UNIT_GATEWAY_BREAKER_KEY("EnergyUnitGatewayBreakerKey", "能量单元网关断路器秘钥"),
        MAX_VIRTUAL_POINT_NUMBER("MaxVirtualPointNumber", "最大虚拟点号"),
        DEVICE_TREE_KEY("DeviceTreeKey", "设备树密钥"),
        ALARM_EVENT_LIST_TIME("AlarmEventListTime", "告警事件列表时间"),
        ALARM_EVENT_LIST("AlarmEventList", "告警事件列表"),
        READY_EVENT_MAP("ReadyEventMap", "待处理告警事件列表"),
        OLD_ALARM_EVENT_LIST("oldAlarmEventList", "旧告警事件列表"),
        SHIFT_KEY("ShiftKey", "交接班密钥"),
        VOLTAGE_HARMONIC_OVERSHOOT("voltageHarmonicOvershoot", "电压谐波越限监测"),
        CURRENT_HARMONIC_OVERSHOOT("currentHarmonicOvershoot", "电流谐波越限监测"),
        VOLTAGE_OVERSHOOT("voltageOvershoot", "电压越限"),
        OVERSHOOT_TASK_KEY("OvershootTaskKey", "越限任务密钥"),
        VPP_DATA_TASK("VppDataTask", "Vpp数据任务"),
        STATION_WORK_STATUS_TASK_KEY("StationWorkStatusTaskKey", "电站工作状态任务密钥"),
        ENERGY_UNIT_WORK_STATUS_REALTIME_KEY("EnergyUnitWorkStatusRealtimeKey", "能量单元工作状态即时密钥"),
        ANALOG_KEY("AnalogKey", "点号密钥"),
        WORK_STATUS("WorkStatus", "工作状态"),
        STRING_CURRENT_STATUS("StringCurrentStatus", "字符串当前状态"),
        ENERGY_UNIT_BATTERY_UNIT_SOC("EnergyUnit_BatteryUnit_Soc", "能量单元_电池单元_Soc"),
        ENERGY_UNIT_TIME_ZONE("EnergyUnit_TimeZone", "能量单元_时区"),
        ALARM_STATUS_("AlarmStatus", "告警状态"),
        DEVICES("Devices", "设备"),
        DEVICES_ANALOGS("DevicesAnalogs", "设备点号"),
        VPP_PV_ELECTRICITY_TASK_KEY("VppPvElectricityTaskKey", "vpp光伏电力任务密钥"),
        DEVICE_DIVERGENCEKEY("Device_Divergence", "vpp光伏电力任务密钥"),
        ENERGY_UNIT_PRODUCTION_TIME("EnergyUnitProductionTime", "能量单元投产时间"),
        RUN_STRATEGY("RunStrategy","控制策略"),
        RECOLLECT("Recollect", "数据补录"),
        CREATE_ALARM("CreateAlarm", "新增告警"),
        BATTERY_DYNAMIC("BatteryDynamic", "电池分容"),
        DPU_FILE("DpuFile", "DPU上传文件");

        private String value;
        private String title;
        KEY(String value, String title) {
            this.value = value;
            this.title = title;
        }
        public String value() {
            return value;
        }
        public String value(Object param) {
            String paramStr = param.toString();
            if (paramStr.length() > 32) {
                paramStr = MD5Util.encode(paramStr);
            }
            return value + SPLIT_STR + paramStr;
        }
        public String title() {
            return title;
        }
    }

    /**
     * 获得name特有Key
     * @param name
     */
    public static String getNameParam(String name) {
        return "name" + SPLIT_STR + name;
    }

    /**
     * 获得id特有Key
     * @param id
     */
    public static String getIdParam(Long id) {
        return "id" + SPLIT_STR + id;
    }

    /**
     * 获得默认存活时间（半小时）
     */
    public static int getDefaultTime() {
        return getRandomTime(LIVE_TIME.HOUR_HALF.value());
    }

    /**
     * 按照传入存活时间进行随机增减（0.8~1.2倍范围）
     * @param liveTime 存活时间
     */
    private static int getRandomTime(int liveTime) {
        double max = 1.2d;
        double min = 0.8d;
        return (int)((Math.random()*(max-min)+min)*liveTime);
    }
}
